﻿using System;
using System.Linq;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;
using ReadyApps.Common;
using ReadyApps.Data;
using ReadyApps.Wiki.Templates;

namespace ReadyApps.Wiki.Views
{
    class WikiEditPermissionsView : IWikiView
    {
        #region Variables and Constants

        private const string VIEW_PAGE_CHECKBOX_PREFIX = "ViewPage_";
        private const string EDIT_PAGE_CHECKBOX_PREFIX = "EditPage_";
        private const string EDIT_PERMISSIONS_CHECKBOX_PREFIX = "EditPermissions_";
        private const string MANAGE_REVISIONS_CHECKBOX_PREFIX = "ManageRevisions_";
        private const string NEW_ROLE_NAME_TEXTBOX_ID = "txtNewRole";
        private const string NEW_VIEW_PAGE_CHECKBOX_ID = "chkNewViewPage";
        private const string NEW_EDIT_PAGE_CHECKBOX_ID = "chkNewEditPage";
        private const string NEW_EDIT_PERMISSIONS_CHECKBOX_ID = "chkNewEditPermissions";
        private const string NEW_MANAGE_REVISIONS_CHECKBOX_ID = "chkNewManageRevisions";

        private IWikiPageState pageState;
        private IWikiDataProvider dataProvider;
        private WikiControlSettings controlSettings;
        private ControlCollection controlsRef;

        #endregion

        #region Events

        private event EventHandler cancelButtonClick;
        public event EventHandler CancelButtonClick
        {
            add { cancelButtonClick += value; }
            remove { cancelButtonClick -= value; }
        }

        private event EventHandler saveButtonClick;
        public event EventHandler SaveButtonClick
        {
            add { saveButtonClick += value; }
            remove { saveButtonClick -= value; }
        }

        private event EventHandler removeSpecificButtonClick;
        public event EventHandler RemoveSpecificButtonClick
        {
            add { removeSpecificButtonClick += value; }
            remove { removeSpecificButtonClick -= value; }
        }

        #endregion

        #region Constructor

        public WikiEditPermissionsView(IWikiPageState wikiPageState, IWikiDataProvider wikiDataProvider, WikiControlSettings wikiControlSettings)
        {
            pageState = wikiPageState;
            dataProvider = wikiDataProvider;
            controlSettings = wikiControlSettings;
        }

        #endregion

        #region Public Methods

        public void BuildControlTree(ControlCollection controls, bool raiseEvents)
        {
            controls.Clear();
            controlsRef = controls;
            Control container = new Control();

            if (pageState.EditPermissionsData == null)
            {
                pageState.EditPermissionsData = dataProvider.GetWikiPageEditPermissions(pageState.PageID.Value);
            }

            // Create the permission tree breadcrumbs
            StringBuilder levelBuilder = new StringBuilder("<p>\n\t");
            foreach (var level in pageState.EditPermissionsData.WikiPermissionLevels)
            {
                if (level.IsActivePermissionSet)
                {
                    levelBuilder.Append("<u>");
                }
                levelBuilder.Append(level.Name);
                if (level.IsActivePermissionSet)
                {
                    levelBuilder.Append("</u>");
                }
                levelBuilder.Append("/");
            }
            levelBuilder.Remove(levelBuilder.Length - 1, 1);
            levelBuilder.Append("\n</p>");
            container.Controls.Add(new Literal() { Text = levelBuilder.ToString() });

            // Display clone permission set message
            if (pageState.EditPermissionsData.PermissionsAreInherited)
            {
                container.Controls.Add(new Literal()
                {
                    Text = @"<p>
These permissions are inherited from a folder and may be associated with
other pages. By checking the checkbox below, the original permissions will
be modified. If the checkbox is not checked, the modified permissions will
only apply to this page.
</p>
<p>"
                });
                CheckBox modifyOriginalPermissions = new CheckBox();
                modifyOriginalPermissions.Checked = pageState.EditPermissionsData.ModifyOriginalPermissions;
                modifyOriginalPermissions.Text = "Modify the original permissions";
                modifyOriginalPermissions.CheckedChanged += new EventHandler(modifyOriginalPermissions_CheckedChanged);
                container.Controls.Add(modifyOriginalPermissions);
                container.Controls.Add(new Literal() { Text = "</p>" });
            }
            else
            {
                container.Controls.Add(new Literal()
                {
                    Text = @"<p>
These permissions are specific to this page. To remove these permissions
and use the permissions from a folder, click the button below.
</p>
<p>"
                });
                Button removeSpecificPermissions = new Button();
                removeSpecificPermissions.Text = "Remove Page-Specific Permissions";
                removeSpecificPermissions.Click += removeSpecificButtonClick;
                container.Controls.Add(removeSpecificPermissions);
                container.Controls.Add(new Literal() { Text = "</p>" });
            }

            // Table opening and header
            container.Controls.Add(new Literal()
            {
                Text = "<table>\n<tr>\n<td></td><td>Role</td><td>View Page</td><td>Edit Page</td><td>Edit Permissions</td>" +
                    "<td>Manage Revisions</td>\n</tr>"
            });

            // Table rows
            foreach (var permission in pageState.EditPermissionsData.WikiPermissions)
            {
                container.Controls.Add(new Literal() { Text = "<tr>\n<td>" });
                LinkButton deletePermission = new LinkButton();
                deletePermission.Text = "Delete";
                deletePermission.CommandArgument = permission.Role;
                deletePermission.Click += new EventHandler(deletePermission_Click);
                container.Controls.Add(deletePermission);
                container.Controls.Add(new Literal() { Text = "</td><td>" + permission.Role + "</td><td>" });

                CheckBox viewPage = new CheckBox();
                viewPage.ID = VIEW_PAGE_CHECKBOX_PREFIX + permission.Role;
                viewPage.Checked = permission.ViewPage;
                viewPage.CheckedChanged += new EventHandler(permission_CheckedChanged);
                container.Controls.Add(viewPage);
                container.Controls.Add(new Literal() { Text = "</td><td>" });

                CheckBox editPage = new CheckBox();
                editPage.ID = EDIT_PAGE_CHECKBOX_PREFIX + permission.Role;
                editPage.Checked = permission.EditPage;
                editPage.CheckedChanged += new EventHandler(permission_CheckedChanged);
                container.Controls.Add(editPage);
                container.Controls.Add(new Literal() { Text = "</td><td>" });

                CheckBox editPermissions = new CheckBox();
                editPermissions.ID = EDIT_PERMISSIONS_CHECKBOX_PREFIX + permission.Role;
                editPermissions.Checked = permission.EditPermissions;
                editPermissions.CheckedChanged += new EventHandler(permission_CheckedChanged);
                container.Controls.Add(editPermissions);
                container.Controls.Add(new Literal() { Text = "</td><td>" });

                CheckBox manageRevisions = new CheckBox();
                manageRevisions.ID = MANAGE_REVISIONS_CHECKBOX_PREFIX + permission.Role;
                manageRevisions.Checked = permission.ManageRevisions;
                manageRevisions.CheckedChanged += new EventHandler(permission_CheckedChanged);
                container.Controls.Add(manageRevisions);
                container.Controls.Add(new Literal() { Text = "</td>\n</tr>" });
            }

            // New permission row
            container.Controls.Add(new Literal() { Text = "<tr>\n<td>" });
            LinkButton addPermission = new LinkButton();
            addPermission.Text = "Add";
            addPermission.Click += new EventHandler(addPermission_Click);
            container.Controls.Add(addPermission);
            container.Controls.Add(new Literal() { Text = "</td><td>" });
            TextBox newRole = new TextBox();
            newRole.ID = NEW_ROLE_NAME_TEXTBOX_ID;
            container.Controls.Add(newRole);
            container.Controls.Add(new Literal() { Text = "</td><td>" });

            CheckBox newViewPage = new CheckBox();
            newViewPage.ID = NEW_VIEW_PAGE_CHECKBOX_ID;
            newViewPage.Checked = true;
            container.Controls.Add(newViewPage);
            container.Controls.Add(new Literal() { Text = "</td><td>" });

            CheckBox newEditPage = new CheckBox();
            newEditPage.ID = NEW_EDIT_PAGE_CHECKBOX_ID;
            container.Controls.Add(newEditPage);
            container.Controls.Add(new Literal() { Text = "</td><td>" });

            CheckBox newEditPermissions = new CheckBox();
            newEditPermissions.ID = NEW_EDIT_PERMISSIONS_CHECKBOX_ID;
            container.Controls.Add(newEditPermissions);
            container.Controls.Add(new Literal() { Text = "</td><td>" });

            CheckBox newManageRevisions = new CheckBox();
            newManageRevisions.ID = NEW_MANAGE_REVISIONS_CHECKBOX_ID;
            container.Controls.Add(newManageRevisions);
            container.Controls.Add(new Literal() { Text = "</td>\n</tr>" });

            // Table closing
            container.Controls.Add(new Literal() { Text = "</table>" });

            WikiControlButton saveButton = WikiControlButton.GetFromTemplate(controlSettings.ButtonTemplate);
            saveButton.ButtonControl.Text = "Save Changes";
            saveButton.ButtonControl.Click += saveButtonClick;
            container.Controls.Add(saveButton.RootControl);

            container.Controls.Add(new Literal() { Text = "&nbsp;" });

            WikiControlButton cancelButton = WikiControlButton.GetFromTemplate(controlSettings.ButtonTemplate);
            cancelButton.ButtonControl.Text = "Cancel Changes";
            cancelButton.ButtonControl.Click += cancelButtonClick;
            container.Controls.Add(cancelButton.RootControl);

            controls.Add(container);
        }

        #endregion

        #region Local Event Handlers

        private void deletePermission_Click(object sender, EventArgs e)
        {
            pageState.EditPermissionsData.RemovePermissions(((LinkButton)sender).CommandArgument);
        }

        private void modifyOriginalPermissions_CheckedChanged(object sender, EventArgs e)
        {
            pageState.EditPermissionsData.ModifyOriginalPermissions = ((CheckBox)sender).Checked;
        }

        private void permission_CheckedChanged(object sender, EventArgs e)
        {
            CheckBox checkbox = (CheckBox)sender;
            if (checkbox.ID.StartsWith(VIEW_PAGE_CHECKBOX_PREFIX))
            {
                string role = checkbox.ID.Substring(VIEW_PAGE_CHECKBOX_PREFIX.Length);
                pageState.EditPermissionsData.WikiPermissions.First(p => p.Role == role).ViewPage = checkbox.Checked;
            }
            else if (checkbox.ID.StartsWith(EDIT_PAGE_CHECKBOX_PREFIX))
            {
                string role = checkbox.ID.Substring(EDIT_PAGE_CHECKBOX_PREFIX.Length);
                pageState.EditPermissionsData.WikiPermissions.First(p => p.Role == role).EditPage = checkbox.Checked;
            }
            else if (checkbox.ID.StartsWith(EDIT_PERMISSIONS_CHECKBOX_PREFIX))
            {
                string role = checkbox.ID.Substring(EDIT_PERMISSIONS_CHECKBOX_PREFIX.Length);
                pageState.EditPermissionsData.WikiPermissions.First(p => p.Role == role).EditPermissions = checkbox.Checked;
            }
            else if (checkbox.ID.StartsWith(MANAGE_REVISIONS_CHECKBOX_PREFIX))
            {
                string role = checkbox.ID.Substring(MANAGE_REVISIONS_CHECKBOX_PREFIX.Length);
                pageState.EditPermissionsData.WikiPermissions.First(p => p.Role == role).ManageRevisions = checkbox.Checked;
            }
        }

        private void addPermission_Click(object sender, EventArgs e)
        {
            string role = ((TextBox)WebUtilities.FindControlRecursive(controlsRef[0], NEW_ROLE_NAME_TEXTBOX_ID)).Text;
            bool viewPage = ((CheckBox)WebUtilities.FindControlRecursive(controlsRef[0], NEW_VIEW_PAGE_CHECKBOX_ID)).Checked;
            bool editPage = ((CheckBox)WebUtilities.FindControlRecursive(controlsRef[0], NEW_EDIT_PAGE_CHECKBOX_ID)).Checked;
            bool editPermissions = ((CheckBox)WebUtilities.FindControlRecursive(controlsRef[0], NEW_EDIT_PERMISSIONS_CHECKBOX_ID)).Checked;
            bool manageRevisions = ((CheckBox)WebUtilities.FindControlRecursive(controlsRef[0], NEW_MANAGE_REVISIONS_CHECKBOX_ID)).Checked;
            pageState.EditPermissionsData.AddPermissions(role, viewPage, editPage, editPermissions, manageRevisions);
        }

        #endregion
    }
}
